package tools.aligning;

import java.io.FileReader;
import java.util.ArrayList;
import java.util.Iterator;

import neobio.alignment.CharSequence;
import neobio.alignment.IncompatibleScoringSchemeException;
import neobio.alignment.ScoringMatrix;

public class aligning extends Thread {

//	Thread t;
//	PairwiseAlignmentAlgorithm method=null;
	ArrayList result=null;
	String name1=null;
	CharSequence seq1=null;
	ArrayList seqs2=null;
	ArrayList names2=null;
	private boolean done=true;
	ScoringMatrix sMat=null;
	
	private String scoringMatrixPath="/home/karln/workspace/jars/blosum62.txt";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
	public aligning(String algorithm)throws Exception{
		
		sMat=new ScoringMatrix(new FileReader(scoringMatrixPath));
//		t=new Thread(this);
	}
	
	public void setData(String n1,CharSequence s1,ArrayList n2,ArrayList s2){
		name1=n1;
		seq1=s1;
		names2=n2;
		seqs2=s2;
		result=new ArrayList();
		done=false;
	}
	
	public void run(){
//		int itt=0;
		for (Iterator i = seqs2.iterator(),j=names2.iterator() ; i.hasNext()&&j.hasNext();) {
			CharSequence seq2 = (CharSequence) i.next();
			String name2= (String) j.next();
			try{
//				System.out.println(itt++);
//				method.loadSequences(seq1,seq2);
				result.add(new alignment(name1,name2,computeScore(seq1,seq2)));
			}catch(Exception e){
				e.printStackTrace(System.out);
				System.out.println("tjo");
				result.add(new alignment(name1,name2,-99999));
			}
		}
		done=true;
	}
	
	public ArrayList getResult(){
		return result;
	}
	public boolean isDone() {
		return done;
	}
	public void setDone(boolean done) {
		this.done = done;
	}

	protected int computeScore (CharSequence seq1,CharSequence seq2) throws IncompatibleScoringSchemeException
	{
		int[]	array;
		int		r, c, rows, cols, tmp, ins, del, sub;

		rows = seq1.length()+1;
		cols = seq2.length()+1;

		if (rows <= cols)
		{
			// goes columnwise
			array = new int [rows];

			// initiate first column
			array[0] = 0;
			for (r = 1; r < rows; r++)
				array[r] = array[r-1] + sMat.scoreDeletion(seq1.charAt(r));

			// calculate the similarity matrix (keep current column only)
			for (c = 1; c < cols; c++)
			{
				// initiate first row (tmp hold values
				// that will be later moved to the array)
				tmp = array[0] + sMat.scoreInsertion(seq2.charAt(c));

				for (r = 1; r < rows; r++)
				{
					ins = array[r] + sMat.scoreInsertion(seq2.charAt(c));
					sub = array[r-1] + sMat.scoreSubstitution(seq1.charAt(r), seq2.charAt(c));
					del = tmp + sMat.scoreDeletion(seq1.charAt(r));

					// move the temp value to the array
					array[r-1] = tmp;

					// choose the greatest
					tmp = max (ins, sub, del);
				}

				// move the temp value to the array
				array[rows - 1] = tmp;
			}

			return array[rows - 1];
		}
		else
		{
			// goes rowwise
			array = new int [cols];

			// initiate first row
			array[0] = 0;
			for (c = 1; c < cols; c++)
				array[c] = array[c-1] + sMat.scoreInsertion(seq2.charAt(c));

			// calculate the similarity matrix (keep current row only)
			for (r = 1; r < rows; r++)
			{
				// initiate first column (tmp hold values
				// that will be later moved to the array)
				tmp = array[0] + sMat.scoreDeletion(seq1.charAt(r));

				for (c = 1; c < cols; c++)
				{
					ins = tmp + sMat.scoreInsertion(seq2.charAt(c));
					sub = array[c-1] + sMat.scoreSubstitution(seq1.charAt(r), seq2.charAt(c));
					del = array[c] + sMat.scoreDeletion(seq1.charAt(r));

					// move the temp value to the array
					array[c-1] = tmp;

					// choose the greatest
					tmp = max (ins, sub, del);
				}

				// move the temp value to the array
				array[cols - 1] = tmp;
			}

			return array[cols - 1];
		}
	}
	protected final int max (int v1, int v2, int v3)
	{
		return (v1 >= v2) ? ((v1 >= v3)? v1 : v3) : ((v2 >= v3)? v2 : v3);
	}
}
